Repository Pattern একটি ডিজাইন প্যাটার্ন যা Data Access Logic এবং Business Logic এর মধ্যে একটি অ্যাবস্ট্রাকশন লেয়ার প্রদান করে। এই প্যাটার্নটি Unit Testing সহজতর করার জন্য খুবই কার্যকর, কারণ এটি আপনার কোডের ডেটাবেস ইন্টারঅ্যাকশনকে মডুলার করে, ফলে মক ডেটাবেস বা ইন-মেমরি ডেটাবেস ব্যবহার করে টেস্ট করা সহজ হয়ে যায়।
Repository Pattern ব্যবহারের মাধ্যমে আপনি আপনার data access layer কে encapsulate করতে পারেন এবং এটি Unit Testing এর জন্য অত্যন্ত উপযোগী করে তুলতে পারেন।
Repository Pattern এর মূল উদ্দেশ্য হলো:
এই প্যাটার্নটি তিনটি প্রধান উপাদান নিয়ে কাজ করে:
Repository Pattern ব্যবহার করে আপনি যখন Unit Testing করবেন, তখন সাধারণত in-memory database বা mock repositories ব্যবহার করে টেস্ট করা হয়। এতে ডেটাবেসের উপর নির্ভরতা কমে যায় এবং টেস্টগুলো দ্রুত চলে। এই কৌশলটি নিশ্চিত করে যে, আপনার কোডের data access layer টেস্ট করা হবে, কিন্তু মূল ডেটাবেসে কোনো পরিবর্তন হবে না।
এখন, চলুন দেখুন কিভাবে Repository Pattern তৈরি করে, এবং ইন-মেমরি ডেটাবেস ব্যবহার করে Unit Test লেখা যায়।
প্রথমে, একটি ইন্টারফেস তৈরি করি যেটি আমাদের ডেটা অ্যাক্সেস লজিকের জন্য প্রয়োজনীয় মেথডগুলো ঘোষণা করবে।
public interface IEmployeeRepository
{
Task<IEnumerable<Employee>> GetAllAsync();
Task<Employee> GetByIdAsync(int id);
Task AddAsync(Employee employee);
Task UpdateAsync(Employee employee);
Task DeleteAsync(int id);
}
এখন, এই ইন্টারফেসের একটি বাস্তবায়ন তৈরি করি, যেখানে EF Core এর DbContext ব্যবহার করে ডেটাবেস অপারেশনগুলো করা হবে।
public class EmployeeRepository : IEmployeeRepository
{
private readonly ApplicationDbContext _context;
public EmployeeRepository(ApplicationDbContext context)
{
_context = context;
}
public async Task<IEnumerable<Employee>> GetAllAsync()
{
return await _context.Employees.ToListAsync();
}
public async Task<Employee> GetByIdAsync(int id)
{
return await _context.Employees.FindAsync(id);
}
public async Task AddAsync(Employee employee)
{
_context.Employees.Add(employee);
await _context.SaveChangesAsync();
}
public async Task UpdateAsync(Employee employee)
{
_context.Employees.Update(employee);
await _context.SaveChangesAsync();
}
public async Task DeleteAsync(int id)
{
var employee = await _context.Employees.FindAsync(id);
if (employee != null)
{
_context.Employees.Remove(employee);
await _context.SaveChangesAsync();
}
}
}
যদি আপনি একাধিক repository ব্যবহার করেন এবং তাদেরকে একটি লেনদেনে (transaction) পরিচালনা করতে চান, তবে আপনি Unit of Work প্যাটার্নও প্রয়োগ করতে পারেন।
public interface IUnitOfWork : IDisposable
{
IEmployeeRepository Employees { get; }
Task<int> CompleteAsync();
}
এটি আপনার DbContext এর মাধ্যমে একত্রে কাজ করার সুবিধা দেয়।
এখন Repository Pattern এর সাথে Unit Test লেখার জন্য, আমরা in-memory database ব্যবহার করব যাতে ডেটাবেসের কোনো পরিবর্তন ছাড়াই কোডটি টেস্ট করা যায়।
NuGet প্যাকেজ:
Microsoft.EntityFrameworkCore.InMemory
– ইন-মেমরি ডেটাবেস ব্যবহার করতে।Moq
– মক অবজেক্ট তৈরির জন্য।dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package Moq
এখন, In-memory database ব্যবহার করে Unit Test লিখি:
public class EmployeeRepositoryTests
{
private DbContextOptions<ApplicationDbContext> _options;
public EmployeeRepositoryTests()
{
_options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "TestDatabase")
.Options;
}
[Fact]
public async Task AddAsync_ShouldAddEmployee()
{
// Arrange
var context = new ApplicationDbContext(_options);
var repository = new EmployeeRepository(context);
var employee = new Employee { Name = "John Doe", Age = 30 };
// Act
await repository.AddAsync(employee);
// Assert
var employees = await context.Employees.ToListAsync();
Assert.Single(employees);
Assert.Equal("John Doe", employees.First().Name);
}
[Fact]
public async Task GetAllAsync_ShouldReturnAllEmployees()
{
// Arrange
var context = new ApplicationDbContext(_options);
var repository = new EmployeeRepository(context);
var employee1 = new Employee { Name = "Jane Doe", Age = 28 };
var employee2 = new Employee { Name = "Mark Smith", Age = 35 };
await repository.AddAsync(employee1);
await repository.AddAsync(employee2);
// Act
var employees = await repository.GetAllAsync();
// Assert
Assert.Equal(2, employees.Count());
}
}
এখানে, আমরা in-memory database ব্যবহার করে EmployeeRepository
টেস্ট করেছি, যেখানে ডেটাবেসে কোনো স্থায়ী পরিবর্তন হয়নি এবং টেস্টগুলো স্বয়ংক্রিয়ভাবে চলে গেছে।
Repository Pattern ব্যবহার করলে আপনি ডেটাবেস ইন্টারঅ্যাকশন এবং বিজনেস লজিককে আলাদা রাখতে পারবেন এবং Unit Testing সহজতর হবে। ইন-মেমরি ডেটাবেস বা মক ডেটাবেস ব্যবহার করে টেস্ট করা সম্ভব, যার ফলে ডেটাবেসের উপর নির্ভরশীলতা কমে যায়। এই প্যাটার্নটি ব্যবহার করলে আপনার অ্যাপ্লিকেশনের কোড টেস্টেবল এবং মডুলার হয়ে ওঠে।
common.read_more